package io.yizoo.system.util;

import com.alibaba.fastjson.JSON;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 线程安全的 HTTP 工具类（基于 Apache HttpClient 连接池）
 */
public class HttpClientUtils {

    // 连接池管理器（线程安全）
    private static final PoolingHttpClientConnectionManager CONNECTION_MANAGER;
    // HttpClient 实例（线程安全）
    private static final CloseableHttpClient HTTP_CLIENT;
    // 默认请求配置（超时时间等）
    private static final RequestConfig DEFAULT_REQUEST_CONFIG;

    static {
        // 初始化连接池
        CONNECTION_MANAGER = new PoolingHttpClientConnectionManager();
        CONNECTION_MANAGER.setMaxTotal(200);          // 最大连接数
        CONNECTION_MANAGER.setDefaultMaxPerRoute(50); // 每个路由的最大连接数

        // 配置全局超时参数
        DEFAULT_REQUEST_CONFIG = RequestConfig.custom()
                .setConnectTimeout(5000)    // 连接超时时间（ms）
                .setSocketTimeout(10000)    // 读取超时时间（ms）
                .setConnectionRequestTimeout(2000) // 从连接池获取连接的超时时间
                .build();

        // 创建 HttpClient
        HTTP_CLIENT = HttpClients.custom()
                .setConnectionManager(CONNECTION_MANAGER)
                .setDefaultRequestConfig(DEFAULT_REQUEST_CONFIG)
                .build();
    }

    // 私有构造方法（禁止实例化）
    private HttpClientUtils() {}

    /**
     * 发送 GET 请求（同步）
     *
     * @param url    请求地址
     * @param params 请求参数（Map 或 null）
     * @return 响应内容（字符串）
     */
    public static String doGet(String url, Map<String, String> params) {
        HttpGet httpGet = null;
        try (CloseableHttpResponse response = HTTP_CLIENT.execute(buildGetRequest(url, params))) {
            return handleResponse(response);
        } catch (IOException | URISyntaxException e) {
            throw new RuntimeException("GET 请求失败: " + e.getMessage(), e);
        } finally {
            if (httpGet != null) {
                httpGet.releaseConnection();
            }
        }
    }
    public static String doPost(String url, Map<String, Object> params) {
        return doPostJson(url, JSON.toJSONString(params));
    }

    /**
     * 发送 POST 请求（同步，JSON 格式）
     *
     * @param url    请求地址
     * @param jsonBody 请求体（JSON 字符串）
     * @return 响应内容（字符串）
     */
    public static String doPostJson(String url, String jsonBody) {
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
        httpPost.setEntity(new StringEntity(jsonBody, StandardCharsets.UTF_8));

        try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpPost)) {
            return handleResponse(response);
        } catch (IOException e) {
            throw new RuntimeException("POST 请求失败: " + e.getMessage(), e);
        } finally {
            httpPost.releaseConnection();
        }
    }

    /**
     * 构建 GET 请求对象（带参数）
     */
    private static HttpGet buildGetRequest(String url, Map<String, String> params) throws URISyntaxException {
        URIBuilder uriBuilder = new URIBuilder(url);
        if (params != null) {
            params.forEach(uriBuilder::addParameter);
        }
        URI uri = uriBuilder.build();
        return new HttpGet(uri);
    }

    /**
     * 处理响应结果
     */
    private static String handleResponse(CloseableHttpResponse response) throws IOException {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) {
            throw new RuntimeException("HTTP 状态码异常: " + statusCode);
        }
        HttpEntity entity = response.getEntity();
        return entity != null ? EntityUtils.toString(entity, StandardCharsets.UTF_8) : null;
    }

    /**
     * 异步 GET 请求（可选，需自行处理回调）
     */
    public static void doGetAsync(String url, Map<String, String> params, ResponseHandler<CloseableHttpResponse> callback) {
        try {
            HttpUriRequest httpGet = buildGetRequest(url, params);
            HTTP_CLIENT.execute(httpGet, callback);
        } catch (Exception e) {
            throw new RuntimeException("异步 GET 请求构建失败: " + e.getMessage(), e);
        }
    }
}
